package ru.sgu.codecenter.fidx.command;

import ru.sgu.codecenter.fidx.OperationFailedException;
import ru.sgu.codecenter.fidx.model.HelpItem;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ShowCommand extends Command {
    @Override
    public String getName() {
        return "show";
    }

    @Override
    public void execute(String[] args) {
        for (String arg : args) {
            rescanDirectory(new File(arg));
        }
    }

    private boolean isDirectoryEmpty(String path) {
        String[] files = new File(path).list();
        return files == null || files.length == 0;
    }

    private boolean isDirectoryScanned(String path) throws IOException {
        File directory = new File(path);
        path = directory.getCanonicalPath();
        if (path.charAt(path.length() - 1) != '\\' && path.charAt(path.length() - 1) != '/') {
            path += "\\";
        }

        return !engine.findByFilePathPrefix(path).isEmpty();
    }

    private void rescanDirectory(File directory) {
        if (!directory.exists()) {
            throw new OperationFailedException("Cannot find directory \"" + directory + "\".");
        }

        if (!directory.isDirectory()) {
            throw new OperationFailedException("\"" + directory + "\" is not a directory.");
        }

        try {
            if (!isDirectoryScanned(directory.getCanonicalPath())) {
                info("\"" + directory.getCanonicalPath() + "\" is not in the index.");
                return;
            }

            ArrayList<String> directoriesInIndex = new ArrayList<String>();
            ArrayList<String> directoriesNotInIndex = new ArrayList<String>();
            ArrayList<String> emptyDirectories = new ArrayList<String>();

            final String[] innerFileNames = directory.list();
            if (innerFileNames != null) {
                for (String innerFileName : innerFileNames) {
                    File innerFile = new File(directory, innerFileName);
                    String path = innerFile.getCanonicalPath();
                    if (innerFile.exists() && innerFile.isDirectory()) {
                        if (isDirectoryEmpty(path)) {
                            emptyDirectories.add(path);
                        } else if (isDirectoryScanned(path)) {
                            directoriesInIndex.add(path);
                        } else {
                            directoriesNotInIndex.add(path);
                        }
                    }
                }
            }

            if (!emptyDirectories.isEmpty()) {
                info("Empty subdirectories:");
                for (String file : emptyDirectories) {
                    info(file);
                }
                info("");
            }

            info("Subdirectories in the index:");
            for (String file : directoriesInIndex) {
                info(file);
            }
            info("");

            info("Subdirectories not in the index:");
            for (String file : directoriesNotInIndex) {
                info(file);
            }
            info("");
        } catch (IOException e) {
            throw new OperationFailedException("Unable to rescan directory \"" + directory + "\"", e);
        }
    }

    @Override
    public List<HelpItem> getHelpItems() {
        List<HelpItem> helpItems = new ArrayList<HelpItem>();
        helpItems.add(new HelpItem(getName() + " <directory>", "find <directory> and subdirectories (not recursively) in the index"));
        return helpItems;
    }
}
